/*
 * PROJECT:     ReactOS API tests
 * LICENSE:     MIT (https://spdx.org/licenses/MIT)
 * PURPOSE:     Tests for asin
 * COPYRIGHT:   Copyright 2021 Timo Kreuzer <timo.kreuzer@reactos.org>
 */

#if !defined(_CRTBLD) && !defined(_M_IX86)
#define _CRTBLD // we don't want inline asin!
#endif
#include "math_helpers.h"

#ifdef _MSC_VER
#pragma function(asin)
#endif

#if !defined(_M_IX86)
#define HAS_ASINF
#elif (defined(TEST_UCRTBASE) || defined(TEST_STATIC_CRT))
#define HAS_LIBM_SSE2
#endif


// These are expected to match exactly
static TESTENTRY_DBL s_asin_exact_tests[] =
{
    { 0x0000000000000000 /*  0.000000 */, 0x0000000000000000 /*  0.000000 */ },
    { 0x8000000000000000 /* -0.000000 */, 0x8000000000000000 /* -0.000000 */ },
    { 0x7ff0000000000000 /*  1.#INF00 */, 0xfff8000000000000 /* -1.#IND00 */ },
    { 0x7ff0000000000001 /*  1.#SNAN0 */, 0x7ff8000000000001 /*  1.#QNAN0 */ },
    { 0x7ff7ffffffffffff /*  1.#SNAN0 */, 0x7fffffffffffffff /*  1.#QNAN0 */ },
    { 0x7ff8000000000000 /*  1.#QNAN0 */, 0x7ff8000000000000 /*  1.#QNAN0 */ },
    { 0x7ff8000000000001 /*  1.#QNAN0 */, 0x7ff8000000000001 /*  1.#QNAN0 */ },
    { 0x7fffffffffffffff /*  1.#QNAN0 */, 0x7fffffffffffffff /*  1.#QNAN0 */ },
    { 0xfff0000000000000 /* -1.#INF00 */, 0xfff8000000000000 /* -1.#IND00 */ },
    { 0xfff0000000000001 /* -1.#SNAN0 */, 0xfff8000000000001 /* -1.#QNAN0 */ },
    { 0xfff7ffffffffffff /* -1.#SNAN0 */, 0xffffffffffffffff /* -1.#QNAN0 */ },
    { 0xfff8000000000000 /* -1.#IND00 */, 0xfff8000000000000 /* -1.#IND00 */ },
    { 0xfff8000000000001 /* -1.#QNAN0 */, 0xfff8000000000001 /* -1.#QNAN0 */ },
    { 0xffffffffffffffff /* -1.#QNAN0 */, 0xffffffffffffffff /* -1.#QNAN0 */ },
};

void Test_asin_exact(void)
{
    for (int i = 0; i < _countof(s_asin_exact_tests); i++)
    {
        double x = u64_to_dbl(s_asin_exact_tests[i].x);
        double z = asin(x);
        ok_eq_dbl_exact("asin", s_asin_exact_tests[i].x, z, s_asin_exact_tests[i].result);
    }
}

// This table is autogenerated by `python gen_math_tests.py asin`
static TESTENTRY_DBL_APPROX s_asin_approx_tests[] =
{
//  {    x,                     {    y_rounded,               y_difference           } }
    {    -0x1.0000000000000p+0, {    -0x1.921fb54442d18p+0,   -0x1.1a62633145c07p-54 }, 1 }, // asin(-1.0) == -1.5707963267948966192
    {    -0x1.f5c28f5c28f5cp-1, {    -0x1.5ed690583be07p+0,   -0x1.9e9b66a311d8ap-54 }, 1 }, // asin(-0.98) == -1.3704614844717769373
    {    -0x1.eb851eb851eb8p-1, {    -0x1.4978fa3269ee1p+0,    0x1.b717be098f6f6p-54 }, 1 }, // asin(-0.96) == -1.2870022175865686467
    {    -0x1.e147ae147ae14p-1, {    -0x1.38fe4cb950b11p+0,    0x1.e2dfb3eb2069ap-55 }, 1 }, // asin(-0.94) == -1.2226303055219355818
    {    -0x1.d70a3d70a3d71p-1, {    -0x1.2b07529b1748ap+0,    0x1.dfd9f2253db3bp-54 }, 1 }, // asin(-0.92) == -1.1680804852142351383
    {    -0x1.ccccccccccccdp-1, {    -0x1.1ea93705fa172p+0,   -0x1.797aca4b76b6ep-55 }, 1 }, // asin(-0.9) == -1.1197695149986342376
    {    -0x1.c28f5c28f5c29p-1, {    -0x1.136bb485f3d91p+0,   -0x1.0250f63168287p-54 }, 1 }, // asin(-0.88) == -1.0758622004540011057
    {    -0x1.b851eb851eb85p-1, {    -0x1.09076ee9d82bbp+0,    0x1.0b30a15ad18cfp-54 }, 1 }, // asin(-0.86) == -1.0352696724805087711
    {    -0x1.ae147ae147ae1p-1, {    -0x1.fe9be811df6cap-1,   -0x1.e691a34db4e07p-56 }, 1 }, // asin(-0.84) == -0.99728322237179980876
    {    -0x1.a3d70a3d70a3ep-1, {    -0x1.ec3e10a736333p-1,    0x1.7a9fc5e44482fp-56 }, 1 }, // asin(-0.8200000000000001) == -0.96141101876410171191
    {    -0x1.999999999999ap-1, {    -0x1.dac670561bb50p-1,   -0x1.358a733684234p-57 }, 1 }, // asin(-0.8) == -0.92729521800161230644
    {    -0x1.8f5c28f5c28f6p-1, {    -0x1.ca11a353bd84cp-1,   -0x1.467d94280ae43p-55 }, 1 }, // asin(-0.78) == -0.89466581723423525206
    {    -0x1.851eb851eb852p-1, {    -0x1.ba042d36663dbp-1,   -0x1.fbcf504ab6298p-56 }, 1 }, // asin(-0.76) == -0.86331311501555366127
    {    -0x1.7ae147ae147aep-1, {    -0x1.aa8832b0b0525p-1,   -0x1.933b3e58bf069p-56 }, 1 }, // asin(-0.74) == -0.83307035834164779829
    {    -0x1.70a3d70a3d70ap-1, {    -0x1.9b8bfa40885bdp-1,    0x1.369448f6ec2a5p-57 }, 1 }, // asin(-0.72) == -0.80380231893302999382
    {    -0x1.6666666666666p-1, {    -0x1.8d00e692afd95p-1,   -0x1.3922d1ae3b05ep-55 }, 1 }, // asin(-0.7) == -0.77539749661075300156
    {    -0x1.5c28f5c28f5c2p-1, {    -0x1.7edabe7a11ffdp-1,    0x1.c00bede5ce97cp-55 }, 1 }, // asin(-0.6799999999999999) == -0.74776263465992049567
    {    -0x1.51eb851eb851ep-1, {    -0x1.710f28188f80cp-1,    0x1.4430a41946ef3p-55 }, 1 }, // asin(-0.6599999999999999) == -0.72081876087008952363
    {    -0x1.47ae147ae147bp-1, {    -0x1.639546d3fd53bp-1,    0x1.fd67514c34733p-56 }, 1 }, // asin(-0.64) == -0.69449826562655600518
    {    -0x1.3d70a3d70a3d7p-1, {    -0x1.5665718f62b97p-1,   -0x1.bc991358a1325p-56 }, 1 }, // asin(-0.62) == -0.66874270320237174848
    {    -0x1.3333333333333p-1, {    -0x1.4978fa3269ee1p-1,    0x1.b7ccaf01ab750p-57 }, 1 }, // asin(-0.6) == -0.64350110879328435905
    {    -0x1.28f5c28f5c290p-1, {    -0x1.3cca01c711853p-1,    0x1.b19be0a95461fp-55 }, 1 }, // asin(-0.5800000000000001) == -0.61872869067225117773
    {    -0x1.1eb851eb851ecp-1, {    -0x1.305355e86c374p-1,   -0x1.894989dc9af71p-55 }, 1 }, // asin(-0.56) == -0.5943858000010622682
    {    -0x1.147ae147ae148p-1, {    -0x1.241055329849fp-1,    0x1.2cb854d604c5cp-55 }, 1 }, // asin(-0.54) == -0.57043710939992194956
    {    -0x1.0a3d70a3d70a4p-1, {    -0x1.17fcd90a0d19fp-1,    0x1.353c5cb21db8ap-57 }, 1 }, // asin(-0.52) == -0.54685095069594412959
    {    -0x1.0000000000000p-1, {    -0x1.0c152382d7366p-1,    0x1.ee6913347c2a6p-55 }, 1 }, // asin(-0.5) == -0.52359877559829887308
    {    -0x1.eb851eb851eb8p-2, {    -0x1.0055d080bb634p-1,    0x1.7c637ca7bf40ap-61 }, 1 }, // asin(-0.48) == -0.50065471240458814186
    {    -0x1.d70a3d70a3d70p-2, {    -0x1.e97792c522be0p-2,   -0x1.0b96a30694468p-58 }, 1 }, // asin(-0.45999999999999996) == -0.4779951985189523392
    {    -0x1.c28f5c28f5c28p-2, {    -0x1.d2887569581c9p-2,    0x1.c3c3b237e51eep-56 }, 1 }, // asin(-0.43999999999999995) == -0.45559867339582330363
    {    -0x1.ae147ae147ae2p-2, {    -0x1.bbd9170937b80p-2,   -0x1.b19e844144ec9p-57 }, 1 }, // asin(-0.42000000000000004) == -0.43344532006988602045
    {    -0x1.999999999999ap-2, {    -0x1.a564ac0e73a34p-2,    0x1.5a5e0fcb713a0p-56 }, 1 }, // asin(-0.4) == -0.41151684606748804361
    {    -0x1.851eb851eb852p-2, {    -0x1.8f26c2a5d5e1dp-2,   -0x1.e49b12ccbe190p-58 }, 1 }, // asin(-0.38) == -0.38979629647426056839
    {    -0x1.70a3d70a3d70ap-2, {    -0x1.791b37f9e8a25p-2,   -0x1.1191d69fe4a0dp-57 }, 1 }, // asin(-0.36) == -0.36826789343663996665
    {    -0x1.5c28f5c28f5c2p-2, {    -0x1.633e2ee53c5b7p-2,   -0x1.eb922ae27b8cap-56 }, 1 }, // asin(-0.33999999999999997) == -0.34691689752716167617
    {    -0x1.47ae147ae147ap-2, {    -0x1.4d8c07dd17d7bp-2,   -0x1.d4f0c7410eb0ep-56 }, 1 }, // asin(-0.31999999999999995) == -0.32572948729463010775
    {    -0x1.3333333333332p-2, {    -0x1.380159e14f6fdp-2,   -0x1.d3d43d740646fp-56 }, 1 }, // asin(-0.29999999999999993) == -0.30469265401539743814
    {    -0x1.1eb851eb851ecp-2, {    -0x1.229aec47638ddp-2,   -0x1.0ab1de3613b5fp-59 }, 1 }, // asin(-0.28) == -0.28379410920832787338
    {    -0x1.0a3d70a3d70a4p-2, {    -0x1.0d55b13e747aep-2,   -0x1.98a6d76cfa277p-57 }, 1 }, // asin(-0.26) == -0.26302220290846890502
    {    -0x1.eb851eb851eb8p-3, {    -0x1.f05d81df0953fp-3,   -0x1.456769fc2eb58p-57 }, 1 }, // asin(-0.24) == -0.24236585103896322362
    {    -0x1.c28f5c28f5c28p-3, {    -0x1.c646aa44819d9p-3,    0x1.ecd5d282692a1p-57 }, 1 }, // asin(-0.21999999999999997) == -0.22181447049679438362
    {    -0x1.9999999999998p-3, {    -0x1.9c618aa4ae23bp-3,   -0x1.73ee81b4de653p-58 }, 1 }, // asin(-0.19999999999999996) == -0.20135792079033074613
    {    -0x1.70a3d70a3d708p-3, {    -0x1.72a90648fbf23p-3,   -0x1.2715d03bb242dp-57 }, 1 }, // asin(-0.17999999999999994) == -0.18098645124654764405
    {    -0x1.47ae147ae147cp-3, {    -0x1.49182e599c593p-3,   -0x1.451467c777603p-57 }, 1 }, // asin(-0.16000000000000003) == -0.16069065295191063185
    {    -0x1.1eb851eb851ecp-3, {    -0x1.1faa3bf43ad3bp-3,    0x1.b6fe6b35dad63p-58 }, 1 }, // asin(-0.14) == -0.14046141470985581372
    {    -0x1.eb851eb851eb8p-4, {    -0x1.ecb5156ece085p-4,   -0x1.9529387ef2efep-59 }, 1 }, // asin(-0.12) == -0.12028988239478806685
    {    -0x1.9999999999998p-4, {    -0x1.9a49276037882p-4,   -0x1.24834eb86e331p-59 }, 1 }, // asin(-0.09999999999999998) == -0.10016742116155977403
    {    -0x1.47ae147ae1478p-4, {    -0x1.4807d13203189p-4,   -0x1.a5ba073be0654p-58 }, 1 }, // asin(-0.07999999999999996) == -0.080085580033658973651
    {    -0x1.eb851eb851eb0p-5, {    -0x1.ebd0bd734d89fp-5,    0x1.9830da45e3bb2p-60 }, 1 }, // asin(-0.05999999999999994) == -0.060036058445278364664
    {    -0x1.47ae147ae1480p-5, {    -0x1.47c4773aebd5ep-5,   -0x1.799551e7e64edp-59 }, 1 }, // asin(-0.040000000000000036) == -0.040010674353988961776
    {    -0x1.47ae147ae1480p-6, {    -0x1.47b3ac64be09fp-6,   -0x1.68519a15711bbp-60 }, 1 }, // asin(-0.020000000000000018) == -0.020001333573390509518
    {                 0x0.0p+0, {                 0x0.0p+0,                 0x0.0p+0 }, 1 }, // asin(0.0) == 0.0
    {     0x1.47ae147ae1480p-6, {     0x1.47b3ac64be09fp-6,    0x1.68519a15711bbp-60 }, 1 }, // asin(0.020000000000000018) == 0.020001333573390509518
    {     0x1.47ae147ae1480p-5, {     0x1.47c4773aebd5ep-5,    0x1.799551e7e64edp-59 }, 1 }, // asin(0.040000000000000036) == 0.040010674353988961776
    {     0x1.eb851eb851ec0p-5, {     0x1.ebd0bd734d8afp-5,   -0x1.5d0c7786dd7dcp-60 }, 1 }, // asin(0.06000000000000005) == 0.060036058445278475887
    {     0x1.47ae147ae1480p-4, {     0x1.4807d13203191p-4,    0x1.c0114cb7ba201p-58 }, 1 }, // asin(0.08000000000000007) == 0.08008558003365908503
    {     0x1.99999999999a0p-4, {     0x1.9a4927603788ap-4,    0x1.770d6faa7406cp-59 }, 1 }, // asin(0.10000000000000009) == 0.10016742116155988561
    {     0x1.eb851eb851ec0p-4, {     0x1.ecb5156ece08dp-4,    0x1.06352941aa8c4p-58 }, 1 }, // asin(0.1200000000000001) == 0.12028988239478817868
    {     0x1.1eb851eb851f0p-3, {     0x1.1faa3bf43ad3fp-3,   -0x1.658331594d1dbp-58 }, 1 }, // asin(0.14000000000000012) == 0.14046141470985592585
    {     0x1.47ae147ae1478p-3, {     0x1.49182e599c58fp-3,    0x1.0f9f4f99cf298p-57 }, 1 }, // asin(0.15999999999999992) == 0.16069065295191051938
    {     0x1.70a3d70a3d708p-3, {     0x1.72a90648fbf23p-3,    0x1.2715d03bb242dp-57 }, 1 }, // asin(0.17999999999999994) == 0.18098645124654764405
    {     0x1.9999999999998p-3, {     0x1.9c618aa4ae23bp-3,    0x1.73ee81b4de653p-58 }, 1 }, // asin(0.19999999999999996) == 0.20135792079033074613
    {     0x1.c28f5c28f5c28p-3, {     0x1.c646aa44819d9p-3,   -0x1.ecd5d282692a1p-57 }, 1 }, // asin(0.21999999999999997) == 0.22181447049679438362
    {     0x1.eb851eb851eb8p-3, {     0x1.f05d81df0953fp-3,    0x1.456769fc2eb58p-57 }, 1 }, // asin(0.24) == 0.24236585103896322362
    {     0x1.0a3d70a3d70a4p-2, {     0x1.0d55b13e747aep-2,    0x1.98a6d76cfa277p-57 }, 1 }, // asin(0.26) == 0.26302220290846890502
    {     0x1.1eb851eb851ecp-2, {     0x1.229aec47638ddp-2,    0x1.0ab1de3613b5fp-59 }, 1 }, // asin(0.28) == 0.28379410920832787338
    {     0x1.3333333333334p-2, {     0x1.380159e14f700p-2,   -0x1.c9489977119aep-56 }, 1 }, // asin(0.30000000000000004) == 0.30469265401539755453
    {     0x1.47ae147ae147cp-2, {     0x1.4d8c07dd17d7ep-2,   -0x1.b964cdcda4892p-56 }, 1 }, // asin(0.32000000000000006) == 0.32572948729463022493
    {     0x1.5c28f5c28f5c4p-2, {     0x1.633e2ee53c5bap-2,   -0x1.92b0f5ff70dd1p-56 }, 1 }, // asin(0.3400000000000001) == 0.34691689752716179422
    {     0x1.70a3d70a3d70cp-2, {     0x1.791b37f9e8a27p-2,    0x1.1bf77ba4d05afp-56 }, 1 }, // asin(0.3600000000000001) == 0.36826789343664008565
    {     0x1.851eb851eb854p-2, {     0x1.8f26c2a5d5e1fp-2,    0x1.1f3ce3082e4d7p-56 }, 1 }, // asin(0.3800000000000001) == 0.38979629647426068842
    {     0x1.999999999999cp-2, {     0x1.a564ac0e73a36p-2,   -0x1.3fa1e939a0d07p-57 }, 1 }, // asin(0.40000000000000013) == 0.41151684606748816475
    {     0x1.ae147ae147ae0p-2, {     0x1.bbd9170937b7ep-2,    0x1.03d8f0de418a8p-61 }, 1 }, // asin(0.41999999999999993) == 0.43344532006988589811
    {     0x1.c28f5c28f5c28p-2, {     0x1.d2887569581c9p-2,   -0x1.c3c3b237e51eep-56 }, 1 }, // asin(0.43999999999999995) == 0.45559867339582330363
    {     0x1.d70a3d70a3d70p-2, {     0x1.e97792c522be0p-2,    0x1.0b96a30694468p-58 }, 1 }, // asin(0.45999999999999996) == 0.4779951985189523392
    {     0x1.eb851eb851eb8p-2, {     0x1.0055d080bb634p-1,   -0x1.7c637ca7bf40ap-61 }, 1 }, // asin(0.48) == 0.50065471240458814186
    {     0x1.0000000000000p-1, {     0x1.0c152382d7366p-1,   -0x1.ee6913347c2a6p-55 }, 1 }, // asin(0.5) == 0.52359877559829887308
    {     0x1.0a3d70a3d70a4p-1, {     0x1.17fcd90a0d19fp-1,   -0x1.353c5cb21db8ap-57 }, 1 }, // asin(0.52) == 0.54685095069594412959
    {     0x1.147ae147ae148p-1, {     0x1.241055329849fp-1,   -0x1.2cb854d604c5cp-55 }, 1 }, // asin(0.54) == 0.57043710939992194956
    {     0x1.1eb851eb851ecp-1, {     0x1.305355e86c374p-1,    0x1.894989dc9af71p-55 }, 1 }, // asin(0.56) == 0.5943858000010622682
    {     0x1.28f5c28f5c290p-1, {     0x1.3cca01c711853p-1,   -0x1.b19be0a95461fp-55 }, 1 }, // asin(0.5800000000000001) == 0.61872869067225117773
    {     0x1.3333333333334p-1, {     0x1.4978fa3269ee2p-1,    0x1.2419a87f2a459p-56 }, 1 }, // asin(0.6000000000000001) == 0.64350110879328449783
    {     0x1.3d70a3d70a3d8p-1, {     0x1.5665718f62b98p-1,    0x1.f76b6a953ef9ep-55 }, 1 }, // asin(0.6200000000000001) == 0.66874270320237188998
    {     0x1.47ae147ae147cp-1, {     0x1.639546d3fd53cp-1,    0x1.afd909f079963p-58 }, 1 }, // asin(0.6400000000000001) == 0.69449826562655614967
    {     0x1.51eb851eb8520p-1, {     0x1.710f28188f80ep-1,    0x1.61e063a682122p-55 }, 1 }, // asin(0.6600000000000001) == 0.72081876087008981919
    {     0x1.5c28f5c28f5c2p-1, {     0x1.7edabe7a11ffdp-1,   -0x1.c00bede5ce97cp-55 }, 1 }, // asin(0.6799999999999999) == 0.74776263465992049567
    {     0x1.6666666666666p-1, {     0x1.8d00e692afd95p-1,    0x1.3922d1ae3b05ep-55 }, 1 }, // asin(0.7) == 0.77539749661075300156
    {     0x1.70a3d70a3d70ap-1, {     0x1.9b8bfa40885bdp-1,   -0x1.369448f6ec2a5p-57 }, 1 }, // asin(0.72) == 0.80380231893302999382
    {     0x1.7ae147ae147aep-1, {     0x1.aa8832b0b0525p-1,    0x1.933b3e58bf069p-56 }, 1 }, // asin(0.74) == 0.83307035834164779829
    {     0x1.851eb851eb852p-1, {     0x1.ba042d36663dbp-1,    0x1.fbcf504ab6298p-56 }, 1 }, // asin(0.76) == 0.86331311501555366127
    {     0x1.8f5c28f5c28f6p-1, {     0x1.ca11a353bd84cp-1,    0x1.467d94280ae43p-55 }, 1 }, // asin(0.78) == 0.89466581723423525206
    {     0x1.999999999999ap-1, {     0x1.dac670561bb50p-1,    0x1.358a733684234p-57 }, 1 }, // asin(0.8) == 0.92729521800161230644
    {     0x1.a3d70a3d70a3ep-1, {     0x1.ec3e10a736333p-1,   -0x1.7a9fc5e44482fp-56 }, 1 }, // asin(0.8200000000000001) == 0.96141101876410171191
    {     0x1.ae147ae147ae2p-1, {     0x1.fe9be811df6ccp-1,    0x1.4a2a7bc81f783p-57 }, 1 }, // asin(0.8400000000000001) == 0.99728322237180001337
    {     0x1.b851eb851eb86p-1, {     0x1.09076ee9d82bcp+0,   -0x1.1fd8cb8d0b966p-54 }, 1 }, // asin(0.8600000000000001) == 1.0352696724805089887
    {     0x1.c28f5c28f5c2ap-1, {     0x1.136bb485f3d92p+0,    0x1.38454d9da0d3ep-54 }, 1 }, // asin(0.8800000000000001) == 1.0758622004540013395
    {     0x1.ccccccccccccep-1, {     0x1.1ea93705fa173p+0,    0x1.53592f90f84c7p-54 }, 1 }, // asin(0.9000000000000001) == 1.1197695149986344923
    {     0x1.d70a3d70a3d70p-1, {     0x1.2b07529b17488p+0,    0x1.05c10df861a86p-54 }, 1 }, // asin(0.9199999999999999) == 1.168080485214234855
    {     0x1.e147ae147ae14p-1, {     0x1.38fe4cb950b11p+0,   -0x1.e2dfb3eb2069ap-55 }, 1 }, // asin(0.94) == 1.2226303055219355818
    {     0x1.eb851eb851eb8p-1, {     0x1.4978fa3269ee1p+0,   -0x1.b717be098f6f6p-54 }, 1 }, // asin(0.96) == 1.2870022175865686467
    {     0x1.f5c28f5c28f5cp-1, {     0x1.5ed690583be07p+0,    0x1.9e9b66a311d8ap-54 }, 1 }, // asin(0.98) == 1.3704614844717769373
    {     0x1.0000000000000p+0, {     0x1.921fb54442d18p+0,    0x1.1a62633145c07p-54 }, 1 }, // asin(1.0) == 1.5707963267948966192
};

void Test_asin_approx(void)
{
    for (int i = 0; i < _countof(s_asin_approx_tests); i++)
    {
        double x = s_asin_approx_tests[i].x;
        double expected = s_asin_approx_tests[i].expected.rounded;
        double z = asin(x);
        int64_t error = abs(ulp_error_precise(&s_asin_approx_tests[i].expected, z));
        ok(error <= s_asin_approx_tests[i].max_error,
            "asin(%.17e) = %.17e, expected %.17e, error %I64d ULPs, max %u ULPs\n",
            x, z, expected, error, s_asin_approx_tests[i].max_error);
    }
}

#if defined(HAS_ASINF)

// These are expected to match exactly
static TESTENTRY_DBL s_asinf_exact_tests[] =
{
    { 0x00000000 /*  0.000000 */, 0x00000000 /*  0.000000 */ },
    { 0x80000000 /* -0.000000 */, 0x00000000 /*  0.000000 */ },
    { 0x7f800000 /*  1.#INF00 */, 0x00000000 /*  0.000000 */ },
    { 0x7f800001 /*  1.#SNAN0 */, 0x00000000 /*  0.000000 */ },
    { 0x7fBFffff /*  1.#SNAN0 */, 0x00000000 /*  0.000000 */ },
    { 0x7fC00000 /*  1.#QNAN0 */, 0x00000000 /*  0.000000 */ },
    { 0x7fC80001 /*  1.#QNAN0 */, 0x00000000 /*  0.000000 */ },
    { 0x7fFfffff /*  1.#QNAN0 */, 0x00000000 /*  0.000000 */ },
    { 0xff800000 /* -1.#INF00 */, 0x00000000 /*  0.000000 */ },
    { 0xff800001 /* -1.#SNAN0 */, 0x00000000 /*  0.000000 */ },
    { 0xffBfffff /* -1.#SNAN0 */, 0x00000000 /*  0.000000 */ },
    { 0xffC00000 /* -1.#IND00 */, 0x00000000 /*  0.000000 */ },
    { 0xfff80001 /* -1.#QNAN0 */, 0x00000000 /*  0.000000 */ },
    { 0xffffffff /* -1.#QNAN0 */, 0x00000000 /*  0.000000 */ },
};

void Test_asinf_exact(void)
{
    for (int i = 0; i < _countof(s_asinf_exact_tests); i++)
    {
        float x = u64_to_dbl(s_asinf_exact_tests[i].x);
        float z = asinf(x);
        ok_eq_flt_exact("asinf", s_asinf_exact_tests[i].x, z, s_asinf_exact_tests[i].result);
    }
}

#endif // defined(HAS_ASINF)

#if defined(HAS_ASINF) || defined(HAS_LIBM_SSE2)

static TESTENTRY_DBL_APPROX s_asinf_approx_tests[] =
{
//  {    x,                     {    y_rounded,               y_difference           } }
    {    -0x1.0000000000000p+0, {    -0x1.921fb54442d18p+0,   -0x1.1a62633145c07p-54 }, 1 }, // asinf(-1.0) == -1.5707963267948966192
    {    -0x1.f5c2900000000p-1, {    -0x1.5ed691f3e5c14p+0,   -0x1.d881aa877f15dp-54 }, 1 }, // asinf(-0.9800000190734863) == -1.3704615803196747906
    {    -0x1.eb851e0000000p-1, {    -0x1.4978f8e9455eap+0,    0x1.673e49ad1c217p-56 }, 1 }, // asinf(-0.9599999785423279) == -1.2870021409520355587
    {    -0x1.e147ae0000000p-1, {    -0x1.38fe4c9b4d1d8p+0,    0x1.d44a6a565c0e7p-54 }, 1 }, // asinf(-0.9399999976158142) == -1.2226302985337634916
    {    -0x1.d70a3e0000000p-1, {    -0x1.2b075351fc774p+0,    0x1.4978eb44e6960p-54 }, 1 }, // asinf(-0.9200000166893005) == -1.1680805277978522479
    {    -0x1.cccccc0000000p-1, {    -0x1.1ea9361b0e22bp+0,   -0x1.4c0b2f53c508dp-54 }, 1 }, // asinf(-0.8999999761581421) == -1.1197694603016639823
    {    -0x1.c28f5c0000000p-1, {    -0x1.136bb45ad5983p+0,    0x1.708ef5d01cb48p-54 }, 1 }, // asinf(-0.8799999952316284) == -1.0758621904147679693
    {    -0x1.b851ec0000000p-1, {    -0x1.09076f623edf2p+0,    0x1.d92e9623a9090p-57 }, 1 }, // asinf(-0.8600000143051147) == -1.0352697005135920044
    {    -0x1.ae147a0000000p-1, {    -0x1.fe9be672ad1cbp-1,    0x1.fac6c7e78bf36p-59 }, 1 }, // asinf(-0.8399999737739563) == -0.9972831740365618557
    {    -0x1.a3d70a0000000p-1, {    -0x1.ec3e103bde0acp-1,    0x1.af2150ecb8644p-55 }, 1 }, // asinf(-0.8199999928474426) == -0.9614110062675726519
    {    -0x1.99999a0000000p-1, {    -0x1.dac67100c65fcp-1,   -0x1.c8a5009f46722p-55 }, 1 }, // asinf(-0.800000011920929) == -0.92729523786982742072
    {    -0x1.8f5c280000000p-1, {    -0x1.ca11a1cb039e5p-1,   -0x1.aa440698aa7e4p-55 }, 1 }, // asinf(-0.7799999713897705) == -0.89466577151489150757
    {    -0x1.851eb80000000p-1, {    -0x1.ba042cb85a8bap-1,   -0x1.b9e48d231a978p-56 }, 1 }, // asinf(-0.7599999904632568) == -0.86331310034190458411
    {    -0x1.7ae1480000000p-1, {    -0x1.aa88332a7bc89p-1,    0x1.ada6176a6a192p-56 }, 1 }, // asinf(-0.7400000095367432) == -0.83307037252042546063
    {    -0x1.70a3d80000000p-1, {    -0x1.9b8bfba2aabc0p-1,   -0x1.1b51cfd714dffp-55 }, 1 }, // asinf(-0.7200000286102295) == -0.80380236015968623294
    {    -0x1.6666660000000p-1, {    -0x1.8d00e6034c58ep-1,    0x1.d7774bcc37269p-58 }, 1 }, // asinf(-0.699999988079071) == -0.77539747991811380139
    {    -0x1.5c28f60000000p-1, {    -0x1.7edabecdddb0ep-1,   -0x1.0e17a478e5dfbp-58 }, 1 }, // asinf(-0.6800000071525574) == -0.74776264441502049795
    {    -0x1.51eb860000000p-1, {    -0x1.710f29446d89ap-1,    0x1.28c1958bbf49bp-59 }, 1 }, // asinf(-0.6600000262260437) == -0.72081879577924046009
    {    -0x1.47ae140000000p-1, {    -0x1.6395463411500p-1,    0x1.ca455446fd3ccp-58 }, 1 }, // asinf(-0.6399999856948853) == -0.69449824700919293097
    {    -0x1.3d70a40000000p-1, {    -0x1.566571c39728ep-1,    0x1.085a5461935a4p-55 }, 1 }, // asinf(-0.6200000047683716) == -0.66874270927981324573
    {    -0x1.3333340000000p-1, {    -0x1.4978fb3269ee4p-1,   -0x1.2419b6d47fa39p-56 }, 1 }, // asinf(-0.6000000238418579) == -0.64350113859560710757
    {    -0x1.28f5c20000000p-1, {    -0x1.3cca01171572cp-1,   -0x1.d8221aa8f537ap-55 }, 1 }, // asinf(-0.5799999833106995) == -0.61872867018494087222
    {    -0x1.1eb8520000000p-1, {    -0x1.30535601246e8p-1,    0x1.238f8e7474374p-55 }, 1 }, // asinf(-0.5600000023841858) == -0.59438580287880157408
    {    -0x1.147ae20000000p-1, {    -0x1.2410560d96e0dp-1,   -0x1.05c5ef10111b0p-55 }, 1 }, // asinf(-0.5400000214576721) == -0.57043713489423600378
    {    -0x1.0a3d700000000p-1, {    -0x1.17fcd84a3d081p-1,    0x1.b60b3c8dc5fe4p-55 }, 1 }, // asinf(-0.5199999809265137) == -0.54685092836599842017
    {    -0x1.0000000000000p-1, {    -0x1.0c152382d7366p-1,    0x1.ee6913347c2a6p-55 }, 1 }, // asinf(-0.5) == -0.52359877559829887308
    {    -0x1.eb851e0000000p-2, {    -0x1.0055d017adba7p-1,   -0x1.0a557943a6e37p-55 }, 1 }, // asinf(-0.47999998927116394) == -0.50065470017476779275
    {    -0x1.d70a3e0000000p-2, {    -0x1.e977936697869p-2,   -0x1.5af3749a35404p-58 }, 1 }, // asinf(-0.46000000834465027) == -0.47799520791693922898
    {    -0x1.c28f5c0000000p-2, {    -0x1.d288753bbb4a3p-2,   -0x1.b8087e333343bp-56 }, 1 }, // asinf(-0.4399999976158142) == -0.45559867074082146697
    {    -0x1.ae147a0000000p-2, {    -0x1.bbd91610fb58ap-2,    0x1.a9e1804c82556p-57 }, 1 }, // asinf(-0.41999998688697815) == -0.43344530562065896007
    {    -0x1.99999a0000000p-2, {    -0x1.a564ac7e2de49p-2,   -0x1.192b0e45db774p-57 }, 1 }, // asinf(-0.4000000059604645) == -0.41151685257088794419
    {    -0x1.851eb80000000p-2, {    -0x1.8f26c24d45a33p-2,    0x1.4a109f0821705p-56 }, 1 }, // asinf(-0.3799999952316284) == -0.38979629131918895211
    {    -0x1.70a3d80000000p-2, {    -0x1.791b3901549f4p-2,    0x1.6c0f7667aaf5fp-56 }, 1 }, // asinf(-0.36000001430511475) == -0.36826790876980839664
    {    -0x1.5c28f60000000p-2, {    -0x1.633e2f2691623p-2,   -0x1.c08929b44d213p-57 }, 1 }, // asinf(-0.3400000035762787) == -0.34691690132999237867
    {    -0x1.47ae140000000p-2, {    -0x1.4d8c075b64a87p-2,    0x1.dbd74ce1333fbp-56 }, 1 }, // asinf(-0.3199999928474426) == -0.32572947974509994436
    {    -0x1.3333340000000p-2, {    -0x1.38015ab7ffc0ep-2,    0x1.3faa7a7a211ffp-56 }, 1 }, // asinf(-0.30000001192092896) == -0.30469266651192659578
    {    -0x1.1eb8520000000p-2, {    -0x1.229aec5cb8e32p-2,    0x1.0a5d03b49a69fp-57 }, 1 }, // asinf(-0.2800000011920929) == -0.28379411045009127867
    {    -0x1.0a3d700000000p-2, {    -0x1.0d55b094c795dp-2,    0x1.3ce8513aac81ep-56 }, 1 }, // asinf(-0.25999999046325684) == -0.26302219303206246184
    {    -0x1.eb851e0000000p-3, {    -0x1.f05d81212ac77p-3,    0x1.2b4b519e59224p-58 }, 1 }, // asinf(-0.23999999463558197) == -0.24236584551303838192
    {    -0x1.c28f5c0000000p-3, {    -0x1.c646aa1a84804p-3,    0x1.ffefc87db4fcap-58 }, 1 }, // asinf(-0.2199999988079071) == -0.22181446927476155401
    {    -0x1.99999a0000000p-3, {    -0x1.9c618b0d31199p-3,    0x1.1dada6710527bp-58 }, 1 }, // asinf(-0.20000000298023224) == -0.20135792383201758406
    {    -0x1.70a3d80000000p-3, {    -0x1.72a90742d32d8p-3,   -0x1.0e59d53b862d9p-58 }, 1 }, // asinf(-0.18000000715255737) == -0.18098645851787043359
    {    -0x1.47ae140000000p-3, {    -0x1.49182ddd2083fp-3,    0x1.07ef7aff76714p-59 }, 1 }, // asinf(-0.1599999964237213) == -0.16069064932895746155
    {    -0x1.1eb8520000000p-3, {    -0x1.1faa3c08e9dadp-3,   -0x1.06686e958bed9p-57 }, 1 }, // asinf(-0.14000000059604645) == -0.14046141531183079666
    {    -0x1.eb851e0000000p-4, {    -0x1.ecb514b524a90p-4,   -0x1.d4b89eb468eacp-59 }, 1 }, // asinf(-0.11999999731779099) == -0.12028987969305604862
    {    -0x1.99999a0000000p-4, {    -0x1.9a4927c721fedp-4,   -0x1.d06f9aba30f2cp-58 }, 1 }, // asinf(-0.10000000149011612) == -0.10016742265918284557
    {    -0x1.47ae140000000p-4, {    -0x1.4807d0b6bcaafp-4,    0x1.535b6e72f1b1cp-59 }, 1 }, // asinf(-0.07999999821186066) == -0.080085578239770011587
    {    -0x1.eb851e0000000p-5, {    -0x1.ebd0bcbaa674cp-5,   -0x1.587046d494473p-59 }, 1 }, // asinf(-0.05999999865889549) == -0.060036057101753389611
    {    -0x1.47ae140000000p-5, {    -0x1.47c476bff15bbp-5,   -0x1.2a9f020c83094p-59 }, 1 }, // asinf(-0.03999999910593033) == -0.040010673459203139416
    {    -0x1.47ae140000000p-6, {    -0x1.47b3abe9d676ep-6,    0x1.7ca8fc735baffp-61 }, 1 }, // asinf(-0.019999999552965164) == -0.020001333126266222139
    {                 0x0.0p+0, {                 0x0.0p+0,                 0x0.0p+0 }, 1 }, // asinf(0.0) == 0.0
    {     0x1.47ae140000000p-6, {     0x1.47b3abe9d676ep-6,   -0x1.7ca8fc735baffp-61 }, 1 }, // asinf(0.019999999552965164) == 0.020001333126266222139
    {     0x1.47ae140000000p-5, {     0x1.47c476bff15bbp-5,    0x1.2a9f020c83094p-59 }, 1 }, // asinf(0.03999999910593033) == 0.040010673459203139416
    {     0x1.eb851e0000000p-5, {     0x1.ebd0bcbaa674cp-5,    0x1.587046d494473p-59 }, 1 }, // asinf(0.05999999865889549) == 0.060036057101753389611
    {     0x1.47ae140000000p-4, {     0x1.4807d0b6bcaafp-4,   -0x1.535b6e72f1b1cp-59 }, 1 }, // asinf(0.07999999821186066) == 0.080085578239770011587
    {     0x1.99999a0000000p-4, {     0x1.9a4927c721fedp-4,    0x1.d06f9aba30f2cp-58 }, 1 }, // asinf(0.10000000149011612) == 0.10016742265918284557
    {     0x1.eb851e0000000p-4, {     0x1.ecb514b524a90p-4,    0x1.d4b89eb468eacp-59 }, 1 }, // asinf(0.11999999731779099) == 0.12028987969305604862
    {     0x1.1eb8520000000p-3, {     0x1.1faa3c08e9dadp-3,    0x1.06686e958bed9p-57 }, 1 }, // asinf(0.14000000059604645) == 0.14046141531183079666
    {     0x1.47ae140000000p-3, {     0x1.49182ddd2083fp-3,   -0x1.07ef7aff76714p-59 }, 1 }, // asinf(0.1599999964237213) == 0.16069064932895746155
    {     0x1.70a3d80000000p-3, {     0x1.72a90742d32d8p-3,    0x1.0e59d53b862d9p-58 }, 1 }, // asinf(0.18000000715255737) == 0.18098645851787043359
    {     0x1.99999a0000000p-3, {     0x1.9c618b0d31199p-3,   -0x1.1dada6710527bp-58 }, 1 }, // asinf(0.20000000298023224) == 0.20135792383201758406
    {     0x1.c28f5c0000000p-3, {     0x1.c646aa1a84804p-3,   -0x1.ffefc87db4fcap-58 }, 1 }, // asinf(0.2199999988079071) == 0.22181446927476155401
    {     0x1.eb851e0000000p-3, {     0x1.f05d81212ac77p-3,   -0x1.2b4b519e59224p-58 }, 1 }, // asinf(0.23999999463558197) == 0.24236584551303838192
    {     0x1.0a3d700000000p-2, {     0x1.0d55b094c795dp-2,   -0x1.3ce8513aac81ep-56 }, 1 }, // asinf(0.25999999046325684) == 0.26302219303206246184
    {     0x1.1eb8520000000p-2, {     0x1.229aec5cb8e32p-2,   -0x1.0a5d03b49a69fp-57 }, 1 }, // asinf(0.2800000011920929) == 0.28379411045009127867
    {     0x1.3333340000000p-2, {     0x1.38015ab7ffc0ep-2,   -0x1.3faa7a7a211ffp-56 }, 1 }, // asinf(0.30000001192092896) == 0.30469266651192659578
    {     0x1.47ae140000000p-2, {     0x1.4d8c075b64a87p-2,   -0x1.dbd74ce1333fbp-56 }, 1 }, // asinf(0.3199999928474426) == 0.32572947974509994436
    {     0x1.5c28f60000000p-2, {     0x1.633e2f2691623p-2,    0x1.c08929b44d213p-57 }, 1 }, // asinf(0.3400000035762787) == 0.34691690132999237867
    {     0x1.70a3d80000000p-2, {     0x1.791b3901549f4p-2,   -0x1.6c0f7667aaf5fp-56 }, 1 }, // asinf(0.36000001430511475) == 0.36826790876980839664
    {     0x1.851eb80000000p-2, {     0x1.8f26c24d45a33p-2,   -0x1.4a109f0821705p-56 }, 1 }, // asinf(0.3799999952316284) == 0.38979629131918895211
    {     0x1.99999a0000000p-2, {     0x1.a564ac7e2de49p-2,    0x1.192b0e45db774p-57 }, 1 }, // asinf(0.4000000059604645) == 0.41151685257088794419
    {     0x1.ae147a0000000p-2, {     0x1.bbd91610fb58ap-2,   -0x1.a9e1804c82556p-57 }, 1 }, // asinf(0.41999998688697815) == 0.43344530562065896007
    {     0x1.c28f5c0000000p-2, {     0x1.d288753bbb4a3p-2,    0x1.b8087e333343bp-56 }, 1 }, // asinf(0.4399999976158142) == 0.45559867074082146697
    {     0x1.d70a3e0000000p-2, {     0x1.e977936697869p-2,    0x1.5af3749a35404p-58 }, 1 }, // asinf(0.46000000834465027) == 0.47799520791693922898
    {     0x1.eb851e0000000p-2, {     0x1.0055d017adba7p-1,    0x1.0a557943a6e37p-55 }, 1 }, // asinf(0.47999998927116394) == 0.50065470017476779275
    {     0x1.0000000000000p-1, {     0x1.0c152382d7366p-1,   -0x1.ee6913347c2a6p-55 }, 1 }, // asinf(0.5) == 0.52359877559829887308
    {     0x1.0a3d700000000p-1, {     0x1.17fcd84a3d081p-1,   -0x1.b60b3c8dc5fe4p-55 }, 1 }, // asinf(0.5199999809265137) == 0.54685092836599842017
    {     0x1.147ae20000000p-1, {     0x1.2410560d96e0dp-1,    0x1.05c5ef10111b0p-55 }, 1 }, // asinf(0.5400000214576721) == 0.57043713489423600378
    {     0x1.1eb8520000000p-1, {     0x1.30535601246e8p-1,   -0x1.238f8e7474374p-55 }, 1 }, // asinf(0.5600000023841858) == 0.59438580287880157408
    {     0x1.28f5c20000000p-1, {     0x1.3cca01171572cp-1,    0x1.d8221aa8f537ap-55 }, 1 }, // asinf(0.5799999833106995) == 0.61872867018494087222
    {     0x1.3333340000000p-1, {     0x1.4978fb3269ee4p-1,    0x1.2419b6d47fa39p-56 }, 1 }, // asinf(0.6000000238418579) == 0.64350113859560710757
    {     0x1.3d70a40000000p-1, {     0x1.566571c39728ep-1,   -0x1.085a5461935a4p-55 }, 1 }, // asinf(0.6200000047683716) == 0.66874270927981324573
    {     0x1.47ae140000000p-1, {     0x1.6395463411500p-1,   -0x1.ca455446fd3ccp-58 }, 1 }, // asinf(0.6399999856948853) == 0.69449824700919293097
    {     0x1.51eb860000000p-1, {     0x1.710f29446d89ap-1,   -0x1.28c1958bbf49bp-59 }, 1 }, // asinf(0.6600000262260437) == 0.72081879577924046009
    {     0x1.5c28f60000000p-1, {     0x1.7edabecdddb0ep-1,    0x1.0e17a478e5dfbp-58 }, 1 }, // asinf(0.6800000071525574) == 0.74776264441502049795
    {     0x1.6666660000000p-1, {     0x1.8d00e6034c58ep-1,   -0x1.d7774bcc37269p-58 }, 1 }, // asinf(0.699999988079071) == 0.77539747991811380139
    {     0x1.70a3d80000000p-1, {     0x1.9b8bfba2aabc0p-1,    0x1.1b51cfd714dffp-55 }, 1 }, // asinf(0.7200000286102295) == 0.80380236015968623294
    {     0x1.7ae1480000000p-1, {     0x1.aa88332a7bc89p-1,   -0x1.ada6176a6a192p-56 }, 1 }, // asinf(0.7400000095367432) == 0.83307037252042546063
    {     0x1.851eb80000000p-1, {     0x1.ba042cb85a8bap-1,    0x1.b9e48d231a978p-56 }, 1 }, // asinf(0.7599999904632568) == 0.86331310034190458411
    {     0x1.8f5c280000000p-1, {     0x1.ca11a1cb039e5p-1,    0x1.aa440698aa7e4p-55 }, 1 }, // asinf(0.7799999713897705) == 0.89466577151489150757
    {     0x1.99999a0000000p-1, {     0x1.dac67100c65fcp-1,    0x1.c8a5009f46722p-55 }, 1 }, // asinf(0.800000011920929) == 0.92729523786982742072
    {     0x1.a3d70a0000000p-1, {     0x1.ec3e103bde0acp-1,   -0x1.af2150ecb8644p-55 }, 1 }, // asinf(0.8199999928474426) == 0.9614110062675726519
    {     0x1.ae147a0000000p-1, {     0x1.fe9be672ad1cbp-1,   -0x1.fac6c7e78bf36p-59 }, 1 }, // asinf(0.8399999737739563) == 0.9972831740365618557
    {     0x1.b851ec0000000p-1, {     0x1.09076f623edf2p+0,   -0x1.d92e9623a9090p-57 }, 1 }, // asinf(0.8600000143051147) == 1.0352697005135920044
    {     0x1.c28f5c0000000p-1, {     0x1.136bb45ad5983p+0,   -0x1.708ef5d01cb48p-54 }, 1 }, // asinf(0.8799999952316284) == 1.0758621904147679693
    {     0x1.cccccc0000000p-1, {     0x1.1ea9361b0e22bp+0,    0x1.4c0b2f53c508dp-54 }, 1 }, // asinf(0.8999999761581421) == 1.1197694603016639823
    {     0x1.d70a3e0000000p-1, {     0x1.2b075351fc774p+0,   -0x1.4978eb44e6960p-54 }, 1 }, // asinf(0.9200000166893005) == 1.1680805277978522479
    {     0x1.e147ae0000000p-1, {     0x1.38fe4c9b4d1d8p+0,   -0x1.d44a6a565c0e7p-54 }, 1 }, // asinf(0.9399999976158142) == 1.2226302985337634916
    {     0x1.eb851e0000000p-1, {     0x1.4978f8e9455eap+0,   -0x1.673e49ad1c217p-56 }, 1 }, // asinf(0.9599999785423279) == 1.2870021409520355587
    {     0x1.f5c2900000000p-1, {     0x1.5ed691f3e5c14p+0,    0x1.d881aa877f15dp-54 }, 1 }, // asinf(0.9800000190734863) == 1.3704615803196747906
    {     0x1.0000000000000p+0, {     0x1.921fb54442d18p+0,    0x1.1a62633145c07p-54 }, 1 }, // asinf(1.0) == 1.5707963267948966192
};

#endif // defined(HAS_ASINF) || defined(HAS_LIBM_SSE2)

#if defined(HAS_ASINF)

void Test_asinf_approx(void)
{
    for (int i = 0; i < _countof(s_asinf_approx_tests); i++)
    {
        float x = s_asinf_approx_tests[i].x;
        float expected = s_asinf_approx_tests[i].expected.rounded;
        float z = asinf(x);
        int64_t error = abs(ulp_error_flt(expected, z));
        ok(error <= s_asin_approx_tests[i].max_error,
            "asin(%.6e) = %.7e, expected %.7e, error %I64d ULPs, max %u ULPs\n",
            x, z, expected, error, s_asin_approx_tests[i].max_error);
    }
}

#endif // defined(HAS_ASINF)

#if defined(HAS_LIBM_SSE2)

__ATTRIBUTE_SSE2__ __m128d __libm_sse2_asin(__m128d Xmm0);

__ATTRIBUTE_SSE2__
void Test_libm_sse2_asin(void)
{
    int i;
    for (i = 0; i < _countof(s_asin_approx_tests); i++)
    {
        double x = s_asin_approx_tests[i].x;
        double expected = s_asin_approx_tests[i].expected.rounded;
        __m128d xmm0 = _mm_set_sd(x);
        __m128d xmm1 = __libm_sse2_asin(xmm0);
        double z = _mm_cvtsd_f64(xmm1);
        int64_t error = ulp_error_precise(&s_asin_approx_tests[i].expected, z);
        ok(error <= s_asin_approx_tests[i].max_error,
            "__libm_sse2_asin(%.17e) = %.17e, expected %.17e, error %I64d ULPs, max %u ULPs\n",
            x, z, expected, error, s_asin_approx_tests[i].max_error);
    }
}

__ATTRIBUTE_SSE2__ __m128 __libm_sse2_asinf(__m128 Xmm0);

__ATTRIBUTE_SSE2__
void Test_libm_sse2_asinf(void)
{
    int i;
    for (i = 0; i < _countof(s_asinf_approx_tests); i++)
    {
        float x = s_asinf_approx_tests[i].x;
        float expected = s_asinf_approx_tests[i].expected.rounded;
        __m128 xmm0 = _mm_set_ps1(x);
        __m128 xmm1 = __libm_sse2_asinf(xmm0);
        float z = _mm_cvtss_f32(xmm1);
        int64_t error = ulp_error_flt(expected, z);
        ok(error <= s_asinf_approx_tests[i].max_error,
            "__libm_sse2_asinf(%.6e) = %.7e, expected %.7e, error %I64d ULPs, max %u ULPs\n",
            x, z, expected, error, s_asinf_approx_tests[i].max_error);
    }
}

#endif // defined(HAS_LIBM_SSE2)

START_TEST(asin)
{
    Test_asin_exact();
    Test_asin_approx();
#if defined(HAS_ASINF)
    Test_asinf_exact();
    Test_asinf_approx();
#endif
#if defined(HAS_LIBM_SSE2)
    Test_libm_sse2_asin();
    Test_libm_sse2_asinf();
#endif
}
